from . import userdb

# 权限缓存
users_permission_cache = {}

# 默认根权限
DEFAULT_PERMISSION = 0


async def build_permission(lst: list) -> dict[str, dict]:
    vfs_tree = {}
    for i in lst:  # 解权限
        path_tmp = i[2].split("/")
        if (len(path_tmp) == 1):
            continue
        if (i[2] == "/"):
            path_tmp = [""]
        cur = vfs_tree  # 按 path 访问树
        last_cur_permission = DEFAULT_PERMISSION
        last_permission_obj = None
        for j in path_tmp:
            if j not in cur:  # 创建
                cur[j] = {
                    "child": {},
                    "permission": last_cur_permission
                }
            last_cur_permission = cur[j]["permission"]
            last_permission_obj = cur[j]
            cur = cur[j]["child"]  # 移动指针
        if (last_permission_obj is not None):  # 继承上级权限
            last_permission_obj["permission"] = i[3]
    return vfs_tree


async def load_permission(username: str):
    if username in users_permission_cache:
        return users_permission_cache[username]  # 取缓存
    result = await userdb.execute("SELECT * FROM vfs WHERE username = ?", False, (username,))
    if result is None or len(result) == 0:
        # 没有记录，返回默认权限
        vtree: dict = {"": {
            "child": {},
            "permission": DEFAULT_PERMISSION
        }}
    else:
        result = list(result)
        # 按目录层级排序
        result.sort(key=lambda x: len(x[2].split("/")))
        vtree = await build_permission(result)  # 建树
    users_permission_cache[username] = vtree  # 写缓存
    return vtree


async def set_permission(username: str, path: str, permission: int):
    # 执行 sql
    await userdb.execute("INSERT OR REPLACE INTO vfs (username, dirpath, permission) VALUES (?, ?, ?)", True, (username, path, permission))
    if (username in users_permission_cache):
        del users_permission_cache[username]  # 删除缓存


async def get_permission(username: str, path: str):
    vtree = await load_permission(username)  # 取权限树
    path_tmp = path.split("/")[1:]  # 处理 path
    if (path == "/"):
        path_tmp = []
    cur = vtree[""]  # 开始遍历
    for j in path_tmp:
        if j not in cur["child"]:
            return cur["permission"]
        cur = cur["child"][j]
    return cur["permission"]  # 返回最终权限


async def rescursive_check_permission(username: str, path: str, level: int = 1) -> bool:
    vtree = await load_permission(username)
    path_tmp = path.split("/")[1:]
    if (path == "/"):
        path_tmp = []
    cur = vtree[""]
    for j in path_tmp:
        if j not in cur["child"]:
            return cur["permission"] >= level
        cur = cur["child"][j]

    def recursive_traverse(data):  # 递归访问
        if 'permission' in data:
            # 使用断言直接退出
            assert data['permission'] >= level
        for i in data['child'].values():
            recursive_traverse(i)
    try:
        recursive_traverse(cur)
    except AssertionError:
        return False
    return True


async def check_permission(username: str, path: str, level: int = 1, rescursive: bool = False) -> bool:  # 检查权限
    if rescursive:
        return await rescursive_check_permission(username, path, level)
    else:
        return await get_permission(username, path) >= level
